/**
    File        : ErrorLog.h
    Description : Message and error display and logging
    Author      : Raymond Marsh
    Created     : 08/01/2009
    Copyright 2009, 2010, 2011, 2012 Raymond Marsh

    This program is distributed under the terms of the GNU General Public License.
    To view a copy of the license see the file 'copying.txt'

    This file is part of the MyMoney Suite.

    MyMoney is free software: you can redistribute it and/or modify it under
    the terms of the GNU General Public License as published by the Free Software Foundation, either
    version 3 of the License, or (at your option) any later version.

    MyMoney is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
    without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along with MyMoney.
    If not, see <http://www.gnu.org/licenses/>.
**/

#ifndef ERRORLOG_H_INCLUDED
#define ERRORLOG_H_INCLUDED

//(* wxWidgets includes
#include <wx/window.h>
#include <wx/string.h>
#include <wx/dialog.h>
#ifndef _DEBUG
#  include <wx/msgdlg.h>
#endif
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/statline.h>
#include <wx/button.h>
#include <wx/checkbox.h>
#include <wx/valgen.h>
#include <wx/datetime.h>
#include <wx/version.h>
#include <fstream>
//*)

//(* C/C++ includes
//*)

//(* other includes
#include "../common/stdafx.h"
#include "version.h"
//*)

//(* defines
#define mmMessageDlg(p, m)       mm::RunMsgDlg(p, m)
#define mmOptMsgDlg(p, m, c, b)  mm::RunOptMsgDlg(p, m, c, b)
#define mmErrorDlg(p, m)         mm::RunErrDlg(p, m, __FILE__, __FUNCTION__, __LINE__)
#define mmFatalErrorDlg(p, m)    mm::RunFatalErrDlg(p, m, __FILE__, __FUNCTION__, __LINE__)
#define mmLogError(p, m)         mm::RunLogError(p, m, __FILE__, __FUNCTION__, __LINE__)
//*)

//(* constants
const unsigned char BTN_NULL   = 0x0;
const unsigned char BTN_OK     = BTN_NULL | 0x01;
const unsigned char BTN_YES    = BTN_NULL | 0x02;
const unsigned char BTN_SAVE   = BTN_NULL | 0x04;
const unsigned char BTN_APPLY  = BTN_NULL | 0x08;
const unsigned char BTN_CLOSE  = BTN_NULL | 0x10;
const unsigned char BTN_NO     = BTN_NULL | 0x20;
const unsigned char BTN_CANCEL = BTN_NULL | 0x40;
const unsigned char BTN_HELP   = BTN_NULL | 0x80;
//*)

namespace mm
{

void LogError(const wxString Message, const char* File, const char* Function, const int Line, const bool IsFatal);
wxString GetTimeStamp();

class CMsgDlgBase// : public wxDialog
{
public:
    CMsgDlgBase();
    virtual ~CMsgDlgBase();

    virtual void OnOK(wxCommandEvent& event)     { ( (wxDialog*)(event.GetEventObject() ) )->EndModal(wxID_OK); }
    virtual void OnYes(wxCommandEvent& event)    { ( (wxDialog*)(event.GetEventObject() ) )->EndModal(wxID_YES); }
    virtual void OnSave(wxCommandEvent& event)   { ( (wxDialog*)(event.GetEventObject() ) )->EndModal(wxID_SAVE); }
    virtual void OnApply(wxCommandEvent& event)  { ( (wxDialog*)(event.GetEventObject() ) )->EndModal(wxID_APPLY); }
    virtual void OnClose(wxCommandEvent& event)  { ( (wxDialog*)(event.GetEventObject() ) )->EndModal(wxID_CLOSE); }
    virtual void OnNo(wxCommandEvent& event)     { ( (wxDialog*)(event.GetEventObject() ) )->EndModal(wxID_NO); }
    virtual void OnCancel(wxCommandEvent& event) { ( (wxDialog*)(event.GetEventObject() ) )->EndModal(wxID_CANCEL); }
    virtual void OnHelp(wxCommandEvent& event)   { ( (wxDialog*)(event.GetEventObject() ) )->EndModal(wxID_HELP); }

protected:
    virtual void SetUpDialog(wxWindow* pParent);
    virtual void AddButtons(wxWindow* pParent, const unsigned char BtnFlags);
    virtual void LogError(bool IsFatal = false);
    virtual void ConnectHandlers(wxWindow* pParent, const unsigned char BtnFlags);

    wxWindow*               m_pParent;
    wxString                m_Msg;
    wxBoxSizer*             m_pSizer;
    wxStdDialogButtonSizer* m_pButtons;
    wxString                m_File;
    wxString                m_Function;
    int                     m_Line;
};

class CMsgDlg : public CMsgDlgBase, public wxDialog
{
public:
    CMsgDlg(wxWindow* pParent, const wxString Message, const unsigned char BtnFlags);
    ~CMsgDlg();

private:
    void OnButtonClick(wxCommandEvent& event);
};



class COptMsgDlg : public CMsgDlgBase, public wxDialog
{
public:
    COptMsgDlg(wxWindow* pParent, const wxString Message, bool* IsChecked, const unsigned char BtnFlags);
    ~COptMsgDlg();
    void ConnectValidatingHandlers(const char Flags);

private:
    void OnButtonClick(wxCommandEvent& event);

    wxCheckBox*             m_pCheckbox;
    bool*                   m_pIsChecked;

    static const long ID_CHECKBOX1;
};



class CErrorDlg : public CMsgDlgBase, public wxDialog
{
public:
    CErrorDlg(wxWindow* pParent, const wxString Message, const char* File, const char* Function, const int Line);
    ~CErrorDlg();

private:
//    void OnOK(wxCommandEvent& event);
};



class CFatalErrorDlg : public CMsgDlgBase, public wxDialog
{
public:
    CFatalErrorDlg(wxWindow* pParent, const wxString Message, const char* File, const char* Function, const int Line);
    ~CFatalErrorDlg();

private:
    void OnOK(wxCommandEvent& event);
};



inline int RunMsgDlg(wxWindow* pParent, const wxString Message, const unsigned char BtnFlags = BTN_OK)
{
    CMsgDlg Dlg(pParent, Message, BtnFlags);
    return Dlg.ShowModal();
}
inline int RunOptMsgDlg(wxWindow* pParent, const wxString Message, bool* pIsChecked, const unsigned char BtnFlags = BTN_OK)
{
    COptMsgDlg Dlg(pParent, Message, pIsChecked, BtnFlags);
    return Dlg.ShowModal();
}
inline int RunErrDlg(wxWindow* pParent, const wxString Message, const char* File, const char* Function, const int Line)
{
#ifdef _DEBUG
    wxString Msg = wxString::Format("\nFile=%s, Function=%s, Line=%i\n%s",File, Function, Line, Message);
    wxFAIL_MSG(Msg);
    return 0;
#else
    CErrorDlg Dlg(pParent, Message, File, Function, Line);
    return Dlg.ShowModal();
#endif
}
inline int RunFatalErrDlg(wxWindow* pParent, const wxString Message, const char* File, const char* Function, const int Line)
{
#ifdef _DEBUG
    wxString Msg = wxString::Format("\nFile=%s, Function=%s, Line=%i\n%s",File, Function, Line, Message);
    wxFAIL_MSG(Msg);
    return 0;
#else
    CFatalErrorDlg Dlg(pParent, Message, File, Function, Line);
    return Dlg.ShowModal();
#endif
}
inline void RunLogError(wxWindow* pParent, const wxString Message, const char* File, const char* Function, const int Line)
{
#ifdef _DEBUG
    wxFAIL_MSG(Message);
    return;
#else
    LogError(Message, File, Function, Line, false);
    return;
#endif
}


}; //namespace mmDlg

#endif // ERRORLOG_H_INCLUDED
